package main

import (
	"fmt"
	"go_study/top/jacktgq/oop/interface/retriever/mock"
	"go_study/top/jacktgq/oop/interface/retriever/real"
	"time"
)

type Retriever interface {
	Get(url string) string
}

type Poster interface {
	Post(url string, form map[string]string) string
}

const url = "http://www.baiu.com"

func download(r Retriever) string {
	return r.Get(url)
}

func submit(p Poster) {
	p.Post(url, map[string]string{
		"name":  "张三",
		"phone": "18855091234",
	})
}

// RetrieverPoster 接口组合
type RetrieverPoster interface {
	Retriever
	Poster
	//Connect(host string)
}

func session(rp RetrieverPoster) string {
	rp.Post(url, map[string]string{
		"contents": "This is another faked baidu.com",
	})
	return rp.Get(url)
}

func main() {
	var r Retriever
	retriever := mock.Retriever{"This is a fake baidu.com"}
	r = &retriever
	inspect(r)

	r = &real.Retriever{
		UserAgent: "Mozilla/5.0",
		Timeout:   time.Minute,
	}
	inspect(r)

	// Type assertion：类型断言，如果类型 不一致会报错
	fmt.Println("Type assertion: YES")
	realRetriever := r.(*real.Retriever)
	fmt.Println(realRetriever.UserAgent)
	fmt.Println("Type assertion: NO")
	if mockRetriever, ok := r.(*mock.Retriever); ok {
		fmt.Println(mockRetriever.Contents)
	} else {
		fmt.Println("Not a mock retriever!")
	}

	//mockRetriever := r.(mock.Retriever)
	//fmt.Println(mockRetriever.Contents)

	//fmt.Println(download(r))

	fmt.Println("Try a session")
	fmt.Println(session(&retriever))
}

func inspect(r Retriever) {
	fmt.Println("Inspecting", r)
	fmt.Printf("> %T %v\n", r, r)
	fmt.Print("> Type switch: ")
	switch v := r.(type) {
	case *mock.Retriever:
		fmt.Println("Contents:", v.Contents)
	case *real.Retriever:
		fmt.Println("UserAgent:", v.UserAgent)
	}
}
